Kernels, RKHS, SVR e SVM
Até agora controlamos flexibilidade por:
Outra possibilidade é penalizar diretamente a complexidade de uma função.
Considere o problema de regressão
\[ Y=g(X)+\varepsilon \]
Na regressão linear, restringimos a função a uma forma específica:
\[ g(x)=\beta_0+\beta_1x \]
Mas e se a relação entre \(X\) e \(Y\) for não linear e não quisermos especificar antecipadamente a forma de \(g\)?
Nota
Precisamos definir em qual conjunto de funções procuraremos \(g\) e como controlar sua complexidade.
Na regressão linear, procuramos um vetor de parâmetros:
\[ \boldsymbol\beta=(\beta_0,\beta_1,\ldots,\beta_p)^\top \]
Nos métodos baseados em RKHS, procuramos diretamente uma função:
\[ \boxed{g\in\mathcal H} \]
onde \(\mathcal H\) representa um espaço de funções.
\[ \text{Regressão linear: procurar }\boldsymbol\beta \qquad\Longrightarrow\qquad \text{RKHS: procurar }g \]
RKHS = Reproducing Kernel Hilbert Space
Em português:
Espaço de Hilbert com Núcleo Reprodutor
Para uma primeira abordagem, podemos pensar em uma RKHS como
\[ \boxed{\text{um espaço estruturado de funções candidatas para }g} \]
Não precisamos, neste momento, aprofundar a definição formal de espaço de Hilbert. Basicamente,
Um espaço de Hilbert permite tratar funções geometricamente como tratamos vetores: podemos definir produto interno, norma, distância e projeção.
Uma RKHS é um espaço de Hilbert de funções no qual um kernel permite avaliar e representar essas funções de maneira particularmente conveniente.
Importante
A ideia principal é que a RKHS fornece uma estrutura matemática para comparar, estimar e regularizar funções.
Uma RKHS está associada a uma função kernel
\[ K(x,x') \]
que relaciona dois pontos \(x\) e \(x'\).
Um exemplo importante é o kernel Gaussiano (RBF):
\[ K(x,x')= \exp\left\{-\frac{(x-x')^2}{2\sigma^2}\right\} \]
Intuitivamente:
\[ x\approx x' \Rightarrow K(x,x')\text{ grande} \]
\[ |x-x'|\text{ grande} \Rightarrow K(x,x')\text{ pequeno} \]
Quanto mais distante \(x\) está de \(x_0\), menor é a similaridade determinada pelo kernel.
Uma função em muitos métodos baseados em RKHS pode ser representada na forma
\[ \boxed{ g(x)=\sum_{i=1}^{n}\alpha_iK(x,x_i) } \]
ou seja,
\[ g(x)= \alpha_1K(x,x_1)+\cdots+\alpha_nK(x,x_n) \]
Cada observação de treinamento contribui para a construção da função.
Nota
Os coeficientes \(\alpha_i\) determinam quanto cada função kernel contribui para a função estimada.
A curva final é uma combinação das funções kernel.
Se procurarmos apenas a função que minimiza
\[ \sum_{i=1}^{n}\left[y_i-g(x_i)\right]^2 \]
podemos obter uma função excessivamente flexível.
\[ \text{flexibilidade excessiva} \quad\Longrightarrow\quad \text{overfitting} \]
Precisamos equilibrar
\[ \boxed{\text{qualidade do ajuste} \quad\times\quad \text{complexidade}} \]
Essa ideia já apareceu em Ridge, Lasso e smoothing splines.
Um problema típico é
\[ \boxed{ \min_{g\in\mathcal H} \left\{ \frac{1}{n}\sum_{i=1}^{n}[y_i-g(x_i)]^2 +\lambda\|g\|_{\mathcal H}^{2} \right\} } \]
Temos dois componentes:
\[ \underbrace{ \frac{1}{n}\sum_{i=1}^{n}[y_i-g(x_i)]^2 }_{\text{erro de ajuste}} + \underbrace{ \lambda\|g\|_{\mathcal H}^{2} }_{\text{penalização da complexidade}} \]
O parâmetro \(\lambda\) controla o compromisso entre ajuste e complexidade.
\[ \lambda\downarrow \Rightarrow \text{penalização menor} \Rightarrow \text{maior flexibilidade} \]
Maior risco de overfitting.
\[ \lambda\uparrow \Rightarrow \text{penalização maior} \Rightarrow \text{menor complexidade} \]
Maior risco de underfitting.
Na regressão Ridge:
\[ \min_{\boldsymbol{\beta}} \left\{ \frac{1}{n} \sum_{i=1}^{n} \left(y_i-\mathbf{x}_i^\top\boldsymbol{\beta}\right)^2 + \lambda \|\boldsymbol{\beta}\|_2^2 \right\} \]
Na RKHS:
\[ \min_{g\in\mathcal H} \left\{ \frac{1}{n}\sum_i[y_i-g(x_i)]^2 +\lambda\|g\|_{\mathcal H}^2 \right\} \]
| Ridge | RKHS |
|---|---|
| estima \(\boldsymbol\beta\) | estima \(g\) |
| penaliza \(\|\boldsymbol\beta\|^2\) | penaliza \(\|g\|_{\mathcal H}^2\) |
| controla coeficientes | controla a complexidade da função |
Se \(\mathcal H\) pode conter um número enorme (até infinito) de funções, como resolver
\[ \min_{g\in\mathcal H} \{\text{erro}+\text{penalização}\}? \]
Parece que precisaríamos procurar em um espaço de dimensão infinita.
Mas um resultado fundamental simplifica o problema.
Para uma ampla classe de problemas regularizados, a solução pode ser escrita como
\[ \boxed{ \hat g(x)=\sum_{i=1}^{n}\hat\alpha_iK(x,x_i) } \]
Assim, em vez de procurar diretamente uma função em \(\mathcal H\), precisamos estimar apenas
\[ \hat\alpha_1,\hat\alpha_2,\ldots,\hat\alpha_n \]
Portanto,
\[ \boxed{ \text{problema em espaço de funções} \longrightarrow \text{problema finito de estimação} } \]
Calculamos o kernel para cada par de observações:
\[ K_{ij}=K(x_i,x_j) \]
Isso produz a matriz kernel, ou matriz de Gram:
\[ \mathbf K= \begin{pmatrix} K(x_1,x_1)&\cdots&K(x_1,x_n)\\ \vdots&\ddots&\vdots\\ K(x_n,x_1)&\cdots&K(x_n,x_n) \end{pmatrix} \]
Nos pontos de treinamento,
\[ \hat{\mathbf y}=\mathbf K\boldsymbol\alpha \]
Podemos imaginar uma transformação
\[ x\longmapsto\phi(x) \]
para um espaço de características potencialmente muito grande.
Em vez de construir explicitamente \(\phi(x)\), calculamos diretamente
\[ \boxed{ K(x,x')= \langle\phi(x),\phi(x')\rangle } \]
Assim, a matriz kernel contém os produtos internos entre as observações no espaço transformado.
Isso é conhecido como kernel trick.
No espaço original, um modelo linear pode ser simples demais para representar os dados.
Podemos imaginar uma transformação
\[ x \longmapsto \phi(x) \]
que leva os dados para um espaço de características mais rico.
Nesse novo espaço, ajustamos um modelo linear em \(\phi(x)\):
\[ f(x) = \mathbf{w}^{\top}\phi(x) \]
mas que pode corresponder a uma relação não linear em \(x\):
\[ \boxed{ x \longrightarrow \phi(x) \longrightarrow \text{modelo linear em } \phi(x) \longrightarrow \text{relação não linear em } x } \]
O kernel trick permite fazer isso implicitamente, sem construir explicitamente todas as novas características \(\phi(x)\).
A combinação da perda quadrática com a regularização em uma RKHS leva ao Kernel Ridge Regression.
Substituindo a representação
\[ g(x)=\sum_{j=1}^{n}\alpha_jK(x_j,x) \]
no problema regularizado, obtemos
\[ \min_{\boldsymbol{\alpha}} \left\{ \frac{1}{n} \left\| \mathbf y-\mathbf K\boldsymbol{\alpha} \right\|_2^2 + \lambda \boldsymbol{\alpha}^{\top} \mathbf K \boldsymbol{\alpha} \right\} \]
Minimizando em relação a \(\boldsymbol{\alpha}\):
\[ \boxed{ \widehat{\boldsymbol{\alpha}} = \left( \mathbf K+n\lambda\mathbf I \right)^{-1} \mathbf y } \]
Assim, um problema de otimização sobre funções é reduzido à estimação dos coeficientes \(\alpha_1,\ldots,\alpha_n\).
A predição em um novo ponto \(x\) é
\[ \boxed{ \hat g(x)=\sum_{i=1}^{n}\hat\alpha_iK(x,x_i) } \]
A mesma estrutura aparece em diferentes métodos:
\[ \boxed{\text{Kernel Ridge Regression}} \]
\[ \boxed{\text{SVM com kernel}} \]
\[ \boxed{\text{Smoothing splines}} \]
\[ \boxed{\text{outros métodos kernel regularizados}} \]
O que muda entre eles é, entre outras coisas, a função de perda, o kernel e a forma de regularização.
Até aqui vimos que um modelo pode ser mais ou menos flexível.
No SVM e no SVR, a ideia central continua sendo:
\[ \boxed{\text{ajustar bem os dados} \quad + \quad \text{evitar complexidade desnecessária}} \]
A diferença é o tipo de problema:
Classificação
Queremos separar grupos com uma fronteira que tenha uma margem grande.
Regressão
Queremos uma função que aceite pequenos erros dentro de uma faixa de tolerância.
Por enquanto, pense em margem para SVM e em tubo de tolerância para SVR. As formulações matemáticas vêm depois.
Imagine duas classes de clientes descritas por duas variáveis:
Queremos prever
\[ Y\in\{-1,+1\} \]
Se os grupos puderem ser separados por uma reta, existem várias fronteiras possíveis.
A pergunta do SVM é:
Qual dessas fronteiras deixa a maior distância possível entre os dois grupos?
Uma fronteira pode classificar corretamente os dados de treinamento e ainda passar muito perto das observações.
O SVM prefere uma fronteira com uma região de segurança maior.
\[ \boxed{\text{essa região de segurança é a margem}} \]
Ideia principal
Entre várias fronteiras capazes de separar as classes, o SVM procura aquela com maior margem.
Para duas variáveis, uma fronteira linear pode ser escrita como
\[ g(\mathbf x)=\mathbf w^T\mathbf x+b \]
Se
\[ \mathbf x= \begin{pmatrix} x_1\\x_2 \end{pmatrix}, \qquad \mathbf w= \begin{pmatrix} w_1\\w_2 \end{pmatrix}, \]
então
\[ g(\mathbf x)=w_1x_1+w_2x_2+b \]
A classificação é feita pelo sinal:
\[ g(\mathbf x)>0 \Rightarrow +1 \qquad g(\mathbf x)<0 \Rightarrow -1 \]
\(\mathbf w\) contém os pesos do modelo e determina a orientação da fronteira. O termo \(b\) desloca essa fronteira.
A fronteira de decisão corresponde aos pontos para os quais
\[ g(\mathbf x)=0, \]
isto é,
\[ \boxed{\mathbf w^T\mathbf x+b=0} \]
No caso de duas variáveis, isso é uma reta.
Em três variáveis, é um plano.
Em dimensões maiores, usamos o nome hiperplano.
Na parametrização usual do SVM, as bordas da margem são
\[ \mathbf w^T\mathbf x+b=+1 \]
e
\[ \mathbf w^T\mathbf x+b=-1 \]
A largura total da margem é
\[ \boxed{\frac{2}{\|\mathbf w\|}} \]
Portanto,
\[ \|\mathbf w\|\downarrow \quad\Rightarrow\quad \text{margem}\uparrow \]
Assim,
\[ \boxed{ \text{maximizar a margem} \Longleftrightarrow \text{minimizar }\frac12\|\mathbf w\|^2 } \]
O termo \(\frac12\|\mathbf w\|^2\) funciona como um controle de complexidade: queremos uma fronteira que classifique bem sem ficar excessivamente ajustada aos dados.
Nem todas as observações têm a mesma importância.
Os pontos mais próximos da fronteira são os que limitam quanto podemos aumentar a margem.
Esses pontos são chamados de vetores de suporte.
\[ \boxed{ \text{vetores de suporte} = \text{observações que sustentam a fronteira} } \]
Se movermos um ponto muito distante da margem, a fronteira pode praticamente não mudar.
Se movermos um vetor de suporte, a fronteira pode mudar bastante.
Em dados reais, nem sempre é possível separar perfeitamente as classes.
No hard margin, exigíamos
\[ y_i g(\mathbf{x}_i) \geq 1 \]
No soft margin, introduzimos uma variável de folga \(\xi_i\):
\[ \boxed{ y_i g(\mathbf{x}_i) \geq 1-\xi_i, \qquad \xi_i\geq 0 } \]
A variável \(\xi_i\) mede quanto precisamos relaxar a condição de margem para acomodar a observação \(i\).
| Valor de \(\xi_i\) | Situação |
|---|---|
| \(\xi_i=0\) | observação \(i\) não viola a margem do SVM |
| \(0<\xi_i<1\) | corretamente classificada, mas dentro da margem |
| \(\xi_i=1\) | sobre a fronteira de decisão |
| \(\xi_i>1\) | classificada incorretamente |
Importante
\(\xi_i>0\) não significa necessariamente erro de classificação.
Uma observação pode estar corretamente classificada e ainda violar a margem.
Da restrição do soft margin,
\[ y_i g(\mathbf{x}_i)\geq 1-\xi_i, \]
obtemos
\[ \xi_i\geq 1-y_i g(\mathbf{x}_i) \]
Como também exigimos
\[ \xi_i\geq0, \]
a menor folga necessária é
\[ \boxed{ \xi_i= \max\left\{0,\;1-y_i g(\mathbf{x}_i)\right\} } \]
Mas essa expressão é exatamente a hinge loss, que é a função de perda do SVM:
\[ \boxed{ L_i= \max\left\{0,\;1-y_i g(\mathbf{x}_i)\right\} } \]
Portanto, na solução ótima,
\[ \boxed{\xi_i=L_i} \]
Qual é a diferença?
Na solução ótima do SVM soft margin, elas assumem o mesmo valor.
Considere
\[ L_i=\max\{0,1-y_i g(\mathbf{x}_i)\} \]
| \(y_i g(\mathbf{x}_i)\) | Situação | \(\xi_i=L_i\) |
|---|---|---|
| \(1.5\) | correta e fora da margem | \(0\) |
| \(1.0\) | sobre a margem | \(0\) |
| \(0.7\) | correta, mas dentro da margem | \(0.3\) |
| \(0\) | sobre a fronteira de decisão | \(1\) |
| \(-0.4\) | classificada incorretamente | \(1.4\) |
Assim, o SVM não pergunta apenas:
“A classe foi prevista corretamente?”
Ele também considera:
“A observação está suficientemente afastada da fronteira?”
A variável de folga \(\xi_i\) mede quanto a observação \(i\) viola a margem:
\[ \small y_i g(\mathbf{x}_i) \geq 1-\xi_i, \qquad \xi_i\geq0. \]
Como queremos o menor valor possível de \(\xi_i\),
\[ \small \xi_i = \max\left\{0,\;1-y_i g(\mathbf{x}_i)\right\} = L_{\text{hinge},i} \]
Portanto, a função objetivo do SVM pode ser escrita como
\[ \small \min_{\mathbf w,b} \left[ \underbrace{\frac{1}{2}\|\mathbf w\|^2}_{\text{regularização}} + C\, \underbrace{ \sum_{i=1}^{n} L_{\text{hinge},i} }_{\text{perda nos dados}} \right] \]
\[ \frac{1}{2}\|\mathbf w\|^2 \]
Favorece uma margem maior e controla a complexidade da solução
\[ L_{\text{hinge},i} = \max\{0,1-y_i g(\mathbf{x}_i)\} \]
Penaliza observações que entram na margem ou são classificadas incorretamente
Conexão com o que já vimos
O SVM segue a mesma ideia de risco empírico regularizado:
\[ \boxed{ \text{Função objetivo} = \text{Regularização} + C\times\text{Perda} } \]
Interpretação
O Parâmetro \(C\) \((C>0)\) controla o compromisso entre
\[ \boxed{ \text{regularização} \quad\longleftrightarrow\quad \text{penalização das violações} } \]
\(C\) pequeno: toleramos mais violações em favor da regularização
\(C\) grande: damos maior prioridade a reduzir as violações da margem
Considere dados em que uma classe esteja aproximadamente no centro e outra ao redor dela.
Nenhuma reta separará bem os grupos no espaço original.
Uma possibilidade seria criar manualmente novas variáveis.
O SVM com kernel faz algo mais conveniente:
\[ \boxed{\text{usa similaridades para construir uma fronteira não linear}} \]
A lógica continua sendo a mesma:
\[ \boxed{\text{margem grande + controle das violações}} \]
O que muda é a forma da fronteira.
Com um kernel, o SVM pode produzir fronteiras não lineares no espaço original.
Um kernel muito utilizado é o RBF:
\[ K(\mathbf x,\mathbf x') = \exp\{-\gamma\|\mathbf x-\mathbf x'\|^2\} \]
Não precisamos construir explicitamente todas as transformações de \(\mathbf x\).
Esse é o kernel trick.
\(\gamma\) controla quão local é a influência de uma observação.
Influência mais ampla
Fronteira tende a ser mais suave
Menor flexibilidade
Influência mais localizada
Fronteira pode ficar mais irregular
Maior flexibilidade
O SVM nasce como classificador binário.
Para mais de duas classes, podemos combinar vários SVMs binários.
One-vs-Rest (OVR)
One-vs-One (OVO)
Agora trocamos o tipo de resposta.
No SVM:
\[ Y=\text{classe} \]
No SVR:
\[ Y=\text{valor quantitativo} \]
A ideia geométrica também muda:
\[ \boxed{\text{SVM: margem ao redor da fronteira}} \]
\[ \boxed{\text{SVR: tubo de tolerância ao redor da função}} \]
Suponha que queremos prever o preço de um imóvel.
Uma previsão de R$ 500.000 para um imóvel que vale R$ 501.000 possui erro de R$ 1.000.
Talvez, para o problema, esse erro seja pequeno demais para merecer atenção.
O SVR permite definir uma tolerância:
\[ \varepsilon \]
Erros menores que essa tolerância podem ser tratados como aceitáveis.
O SVR procura uma função \(g(\mathbf x)\) e cria ao redor dela uma faixa:
\[ g(\mathbf x)-\varepsilon \leq y \leq g(\mathbf x)+\varepsilon \]
A largura total é
\[ 2\varepsilon \]
Se
\[ |y_i-g(\mathbf x_i)|\leq\varepsilon, \]
a observação está dentro do tubo.
Nesse caso, o SVR atribui perda zero a esse erro.
A função de perda é
\[ \boxed{ L_\varepsilon(y,g(\mathbf x)) = \max\{0,|y-g(\mathbf x)|-\varepsilon\} } \]
Sua leitura é simples:
\[ |y-g(\mathbf x)|\leq\varepsilon \Rightarrow L_\varepsilon=0 \]
e
\[ |y-g(\mathbf x)|>\varepsilon \Rightarrow L_\varepsilon>0 \]
Diferentemente do erro quadrático, o SVR possui uma zona de tolerância: pequenos erros podem ser ignorados.
A função objetivo do SVR pode então ser escrita diretamente como
\[ \min_{\mathbf w,b} \left[ \underbrace{\frac{1}{2}\|\mathbf w\|^2}_{\text{regularização}} + C\, \underbrace{ \sum_{i=1}^{n} L_{\varepsilon}\left(y_i,g(\mathbf{x}_i)\right) }_{\text{perda nos dados}} \right] \]
\[ \frac{1}{2}\|\mathbf w\|^2 \]
Controla a complexidade da função estimada.
Quanto maior seu peso relativo, maior a preferência por uma solução mais regularizada
\[ L_{\varepsilon} = \max\{0,|y_i-g(\mathbf{x}_i)|-\varepsilon\} \]
Ideia central
Assim como no SVM,
\[ \boxed{ \text{Função objetivo} = \text{Regularização} + C\times\text{Perda} } \]
No SVR, a perda é a \(\varepsilon\)-insensível e \(C>0\) controla quanto penalizamos as observações que ultrapassam o tubo.
Considere três tipos de observações:
| Posição | Papel |
|---|---|
| dentro do tubo | geralmente não determina diretamente a solução |
| sobre a borda do tubo | pode ser vetor de suporte |
| fora do tubo | pode ser vetor de suporte e gera penalização |
Assim,
\[ \boxed{ \text{vetores de suporte} = \text{pontos que ajudam a determinar o tubo e a função} } \]
Essa é a origem do nome Support Vector Regression.
\(\varepsilon\) responde a pergunta:
Qual erro considero pequeno o suficiente para ignorar?
\[ \varepsilon\uparrow \Rightarrow \text{tubo mais largo} \Rightarrow \text{mais erros com perda zero} \]
\[ \varepsilon\downarrow \Rightarrow \text{tubo mais estreito} \Rightarrow \text{mais observações influenciam o ajuste} \]
Se a relação entre \(X\) e \(Y\) não for linear, podemos utilizar kernels.
Com RBF, por exemplo,
\[
K(\mathbf x,\mathbf x')
=
\exp\{-\gamma\|\mathbf x-\mathbf x'\|^2\}
\]
Observação
\[ (C,\varepsilon,\gamma) \quad\text{são hiperparâmetros} \]
e devem ser escolhidos com dados de treinamento, tipicamente por validação cruzada.
A minimização da função objetivo leva a uma solução da forma
\[ \boxed{ \hat g(\mathbf{x}) = \sum_{i=1}^{n} (\alpha_i-\alpha_i^*) K(\mathbf{x}_i,\mathbf{x}) +b } \]
em que \(\alpha_i\) e \(\alpha_i^*\) são coeficientes determinados durante a otimização.
Para observações estritamente dentro do tubo de tolerância, ou seja, \(|y_i-\hat g(\mathbf{x}_i)|<\varepsilon,\) temos
\[ \alpha_i=\alpha_i^*=0. \]
Logo, essas observações não são vetores de suporte e não contribuem diretamente para a função estimada.
Assim, podemos pensar na solução como
\[ \boxed{ \hat g(\mathbf{x}) = \sum_{i\in SV} (\alpha_i-\alpha_i^*) K(\mathbf{x}_i,\mathbf{x}) +b } \]
onde \(SV\) representa o conjunto dos vetores de suporte.
Em geral,
\[ \alpha_i=\alpha_i^*=0 \]
e a observação não participa diretamente da solução
Podemos ter
\[ \alpha_i-\alpha_i^*\neq0 \]
Essas observações são os vetores de suporte
Ideia central
A função estimada pelo SVR é construída principalmente a partir das observações que definem ou violam o tubo de tolerância.
EST335 — Semana 6